package ace.tool.generate.code.impl.resolver.scheme.resolver;

import ace.tool.generate.code.impl.resolver.scheme.model.dto.ProjectInfo;
import ace.tool.generate.code.impl.resolver.util.ProjectUtils;
import java.util.HashMap;
import java.util.Map;
import lombok.Builder;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringSubstitutor;

/**
 * @author caspar
 * @date 2023/11/17 10:34
 */
@Builder
@RequiredArgsConstructor
public class ProjectInfoResolver {
  private final String projectNamePrefix;
  private final String projectNameSuffix;
  private final String projectName;
  private final String projectDisplayName;
  private final String projectRootDir;

  public ProjectInfo resolve() {
    return ProjectInfo.builder()
        .mavenArtifactId(this.getMavenArtifactId())
        .pomFileFullName(this.getPomFileFullName())
        .readmeFileFullName(this.getReadmeFileFullName())
        .sourceCodeRootDir(this.getSourceCodeRootDir())
        .resourcesRootDir(this.getResourcesRootDir())
        .rootDir(this.getProjectFileFullName())
        .testResourcesRootDir(this.getTestResourcesRootDir())
        .testSourceCodeRootDir(this.getTestSourceCodeRootDir())
        .projectModuleDisplayName(this.getProjectModuleDisplayName())
        .projectModuleName(this.getProjectModuleName())
        .build();
  }

  private String getProjectModuleName() {
    return ProjectUtils.getProjectModuleCodeName(this.projectName);
  }

  private String getProjectModuleDisplayName() {
    return StringUtils.isBlank(this.projectDisplayName)
        ? this.projectName
        : this.projectDisplayName;
  }

  private String getTestSourceCodeRootDir() {
    String projectFileFullName = this.getProjectFileFullName();
    Map<String, String> data = new HashMap<>();
    data.put("projectFileFullName", projectFileFullName);
    return StringSubstitutor.replace("${projectFileFullName}/src/test/java", data);
  }

  private String getTestResourcesRootDir() {
    String projectFileFullName = this.getProjectFileFullName();
    Map<String, String> data = new HashMap<>();
    data.put("projectFileFullName", projectFileFullName);
    return StringSubstitutor.replace("${projectFileFullName}/src/test/resources", data);
  }

  public String getSourceCodeRootDir() {
    String projectFileFullName = this.getProjectFileFullName();
    Map<String, String> data = new HashMap<>();
    data.put("projectFileFullName", projectFileFullName);
    return StringSubstitutor.replace("${projectFileFullName}/src/main/java", data);
  }

  public String getResourcesRootDir() {
    String projectFileFullName = this.getProjectFileFullName();
    Map<String, String> data = new HashMap<>();
    data.put("projectFileFullName", projectFileFullName);
    return StringSubstitutor.replace("${projectFileFullName}/src/main/resources", data);
  }

  public String getPomFileFullName() {
    String projectFileFullName = this.getProjectFileFullName();
    Map<String, String> data = new HashMap<>();
    data.put("projectFileFullName", projectFileFullName);
    return StringSubstitutor.replace("${projectFileFullName}/pom.xml", data);
  }

  public String getReadmeFileFullName() {
    String projectFileFullName = this.getProjectFileFullName();
    Map<String, String> data = new HashMap<>();
    data.put("projectFileFullName", projectFileFullName);
    return StringSubstitutor.replace("${projectFileFullName}/readme.md", data);
  }

  public String getMavenArtifactId() {
    Map<String, String> data = new HashMap<>();
    data.put("projectNamePrefix", this.projectNamePrefix);
    data.put("projectNameSuffix", this.projectNameSuffix);
    data.put("projectName", this.projectName);
    return StringSubstitutor.replace(
        "${projectNamePrefix}-${projectName}${projectNameSuffix}", data);
  }

  public String getProjectFileFullName() {
    String projectFileName = this.getMavenArtifactId();
    Map<String, String> data = new HashMap<>();
    data.put("projectRootDir", this.projectRootDir);
    data.put("projectFileName", projectFileName);
    return StringSubstitutor.replace("${projectRootDir}/${projectFileName}", data);
  }
}
